package com.huawei.esdk.tpoa.tools.cxf.utils;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import com.huawei.esdk.tpoa.tools.cxf.interceptor.MsgInInterceptor;
import com.huawei.esdk.tpoa.tools.cxf.interceptor.MsgOutInterceptor;

public abstract class ClientProvider
{
//	private static final Logger LOGGER = Logger.getLogger(ClientProvider.class.getName());
    private static Map<String,Object> clientMap = new HashMap<String,Object>();

    @SuppressWarnings("unchecked")
	public synchronized static<T>  T getClient(Class<T> clz, String url)
    {
        Object clientObj = clientMap.get(clz.getName());
        if (null != clientObj)
        {
            return (T)clientObj;
        }
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        String urlFormat = PropertiesUtils.getValue("smcserver.url.format");
        url = urlFormat.replace("${ip}", url);
        System.out.println("SMC Service Address:" + url);
        
        factory.setAddress(url);

        Object service = null;
        service = factory.create(clz);
        Client client = ClientProxy.getClient(service);

        // Add the header info
        // client.getRequestContext().put(Header.HEADER_LIST, prepareHeaders());
//        if(Boolean.valueOf(PropertiesUtils.getValue("logging")))
//        {
//	        client.getOutInterceptors().add(new TPLoggingOutInterceptor());
//	        client.getInInterceptors().add(new TPLoggingInInterceptor());
//        }

        client.getOutInterceptors().add(new MsgOutInterceptor());
        client.getInInterceptors().add(new MsgInInterceptor());

        // Setting HTTP Related information
        HTTPConduit http = (HTTPConduit) client.getConduit();
        if (null == http) {
			return null;
		}
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setConnectionTimeout(35000);
        httpClientPolicy.setAllowChunking(false);
        httpClientPolicy.setReceiveTimeout(30000);
        http.setClient(httpClientPolicy);

        /**
         *  设置https连接方式，开始
         */
        try
        {
            configSSL(http);
        }
        catch (KeyManagementException e)
        {
            e.printStackTrace();
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        /**
         * 结束
         */
        
        clientMap.put(clz.getName(), service);
        return (T)service;
    }

    private static void configSSL(HTTPConduit http) 
        throws NoSuchAlgorithmException, KeyManagementException
    {
        
        X509TrustManager tm = new X509TrustManager()
        {
            public java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
                return new java.security.cert.X509Certificate[] {};
            }
            
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
                throws java.security.cert.CertificateException
            {
            }
            
            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
                throws java.security.cert.CertificateException
            {
            }
            
        };

        org.apache.cxf.configuration.jsse.TLSClientParameters  tlsParams =
            new  org.apache.cxf.configuration.jsse.TLSClientParameters();
        
        TrustManager[] trustManagers = new TrustManager[] {tm};

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustManagers, new java.security.SecureRandom());
        SSLSocketFactory ssf = sslContext.getSocketFactory();
        
        tlsParams.setSSLSocketFactory(ssf);
        tlsParams.setTrustManagers(trustManagers);
        tlsParams.setUseHttpsURLConnectionDefaultHostnameVerifier(false);
        tlsParams.setDisableCNCheck(true);

        http.setTlsClientParameters(tlsParams);
    }
    
}